package com.ztsoft.user.service.user.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ztsoft.user.mapper.user.*;
import com.ztsoft.user.pojo.constant.UserConstant;
import com.ztsoft.user.pojo.entity.project.Project;
import com.ztsoft.user.pojo.entity.project.UserManage;
import com.ztsoft.user.pojo.entity.project.UserProject;
import com.ztsoft.user.pojo.entity.user.*;
import com.ztsoft.user.pojo.enums.ResultCode;
import com.ztsoft.user.pojo.vo.user.*;
import com.ztsoft.user.service.project.ProjectService;
import com.ztsoft.user.service.project.UserManageService;
import com.ztsoft.user.service.project.UserProjectService;
import com.ztsoft.user.service.user.SysUserDemandService;
import com.ztsoft.user.service.user.SysUserService;
import com.ztsoft.user.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Resource
    private SysUserMapper userMapper;
    @Resource
    private SysUserRoleMapper userRoleMapper;
    @Resource
    private SysRoleMapper roleMapper;
    @Resource
    private SysRoleMenuMapper roleMenuMapper;
    @Resource
    private SysMenuMapper menuMapper;
    @Resource
    private SysDeptMapper deptMapper;
    @Resource
    private SysUserDemandService sysUserDemandService;
    @Resource
    private UserManageService userManageService;
    @Resource
    private ProjectService projectService;
    @Resource
    private UserProjectService userProjectService;

    @Override
    public Result<Object> queryUserByPage(SysUser user, Integer currentPage, Integer pageSize) {
        try {
            Map<String, Object> resultMap = new HashMap<>();

            // 点击 "部门列表" 查询全部
            if (user.getDeptId() != null && user.getDeptId() == 1) {
                user.setDeptId(null);
            }

            // 查询用户基本信息
            QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>(user);
            queryWrapper.orderByDesc("create_time");
            IPage<SysUser> page = this.page(new Page<>(currentPage, pageSize), queryWrapper);
            List<SysUserVo> list = user.getUserInfo(page.getRecords());

            // 组装部门信息
            if (user.getDeptId() != null) {
                list.forEach(sysUserVo -> sysUserVo.setDeptName(deptMapper.selectById(sysUserVo.getDeptId()).getDeptName()));
            }

            // 组装角色信息
            for (SysUserVo sysUserVo : list) {
                QueryWrapper<SysUserRole> queryWrapper2 = new QueryWrapper<>();
                queryWrapper2.eq("user_id", sysUserVo.getUserId());
                SysUserRole sysUserRole = userRoleMapper.selectOne(queryWrapper2);
                if (sysUserRole != null) {
                    QueryWrapper<SysRole> queryWrapper3 = new QueryWrapper<>();
                    queryWrapper3.eq("role_id", sysUserRole.getRoleId());
                    SysRole sysRole = roleMapper.selectOne(queryWrapper3);
                    SysRoleVo sysRoleVo = BeanUtil.copyProperties(sysRole, SysRoleVo.class);
                    sysUserVo.setSysRoleVo(sysRoleVo);
                }
            }

            // 组装返回前端信息
            resultMap.put("total", page.getTotal());
            resultMap.put("result", list);

            return Result.success(resultMap);
        } catch (Exception e) {
            log.error("出现异常", e);
            return Result.fail();
        }
    }

    @Override
    public Result<Object> addUser(SysUserVo sysUserVo) {
        // 添加用户数据
        SysUser user = BeanUtil.copyProperties(sysUserVo, SysUser.class);
        user.setStatus(Boolean.TRUE.equals(sysUserVo.getStatus()) ? 1 : 2);
        save(user);

        // 添加用户到角色关联
        SysRoleVo sysRoleVo = sysUserVo.getSysRoleVo();
        SysUserRole sysUserRole = new SysUserRole(user.getUserId(), sysRoleVo.getRoleId());
        userRoleMapper.insert(sysUserRole);

        // 添加用户到需求单位关联
        if (ObjectUtil.isNotNull(sysUserVo.getDemandUnitId())) {
            sysUserDemandService.save(new SysUserDemand(user.getUserId(), sysUserVo.getDemandUnitId()));
        }

        // 添加管理者与用户关联
        List<SysUser> adminUserList = getAdmin();
        for (SysUser adminUser : adminUserList) {
            userManageService.save(new UserManage(adminUser.getUserId(), user.getUserId()));
        }

        return Result.success();
    }

    @Override
    public Result<Object> updateUser(SysUserVo sysUserVo) {
        SysUser user = BeanUtil.copyProperties(sysUserVo, SysUser.class);
        user.setStatus(Boolean.TRUE.equals(sysUserVo.getStatus()) ? 1 : 2);

        // 修改用户与角色关联
        userRoleMapper.delete(new QueryWrapper<SysUserRole>().eq("user_id", sysUserVo.getUserId()));
        SysRoleVo sysRoleVo = sysUserVo.getSysRoleVo();
        userRoleMapper.insert(new SysUserRole(user.getUserId(), sysRoleVo.getRoleId()));

        // 修改用户与需求单位关联
        String demandUnitId = sysUserVo.getDemandUnitId();
        SysUserDemand sysUserDemand = new SysUserDemand(sysUserVo.getUserId(), demandUnitId);
        sysUserDemandService.remove(new QueryWrapper<SysUserDemand>().eq("user_id", sysUserVo.getUserId()));
        sysUserDemandService.save(sysUserDemand);

        boolean isSuccess = updateById(user);
        if (isSuccess) {
            return Result.success();
        }
        return Result.fail();
    }

    @Override
    public Result<Object> deleteUser(String id) {
        // 删除用户与角色关联
        userRoleMapper.delete(new QueryWrapper<SysUserRole>().eq("user_id", id));

        // 删除用户与需求单位关联
        sysUserDemandService.remove(new QueryWrapper<SysUserDemand>().eq("user_id", id));

        // 删除管理者与用户关联
        userManageService.remove(new QueryWrapper<UserManage>().eq("user_id", id));

        // 删除用户
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", id);
        userRoleMapper.delete(queryWrapper);
        boolean isSuccess = this.removeById(id);
        if (isSuccess) {
            return Result.success();
        }
        return Result.fail();
    }

    @Override
    public Result<Object> login(Map<String, Object> map) {
        Map<String, String> payloadMap = new HashMap<>();

        // 获取查询条件
        String account = map.get("account").toString();
        String password = map.get("password").toString();

        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_account", account);
        SysUser sysUser = this.getOne(queryWrapper);
        if (Objects.isNull(sysUser)) {
            // 账号不存在
            return Result.returnMsg(ResultCode.USER_LOGIN_FAIL.getMsg(), ResultCode.USER_LOGIN_FAIL.getCode());
        } else if (!sysUser.getUserPassword().equals(password)) {
            // 密码错误
            return Result.returnMsg(ResultCode.USER_LOGIN_FAIL.getMsg(), ResultCode.USER_LOGIN_FAIL.getCode());
        }

        // 设值，签发token
        payloadMap.put("account", account);
        String token = JWTUtils.sign(payloadMap);
        return Result.success(token);
    }

    @Override
    public Result<Object> getInfo() {
        Map<String, Object> resultMap = new HashMap<>();

        UserHolder userInfo = this.getUserInfo();
        SysUser sysUser = userInfo.getSysUser();
        SysUserDto sysUserDto = new SysUserDto();
        BeanUtil.copyProperties(sysUser, sysUserDto);
        List<SysRole> roleList = userInfo.getRoleList();
        List<SysMenu> menuList = userInfo.getMenuList();

        Set<String> roleNameList = new HashSet<>();
        Set<String> permissionNameList = new HashSet<>();

        roleList.forEach(role -> roleNameList.add(role.getRoleName()));
        menuList.stream().filter(menu -> Objects.equals(menu.getMenuType(), "F")).forEach((menu -> permissionNameList.add(menu.getPerms())));

        // 封装结果集
        resultMap.put("user", sysUserDto);
        resultMap.put("roles", roleNameList);
        resultMap.put("permission", permissionNameList);
        return Result.success(resultMap);
    }

    @Override
    public Result<Object> getRouters() {
        UserHolder userInfo = this.getUserInfo();
        List<SysMenu> menuList = userInfo.getMenuList();

        List<SysMenu> collect = menuList.stream().filter(menu -> !Objects.equals(menu.getMenuType(), "F")).collect(Collectors.toList());
        List<Route> routes = new ArrayList<>();
        for (SysMenu menu : collect) {
            Route route = BeanUtil.copyProperties(menu, Route.class);
            route.setHidden(menu.getHideMenu() == 2);
            route.setAlwayShow(menu.getAlwayShow() == 1);
            Meta meta = BeanUtil.copyProperties(menu, Meta.class);
            meta.setTitle(menu.getMenuName());
            meta.setActiveMenu(menu.getActionMenu());
            meta.setHideTabs(menu.getHideTabs());
            route.setMeta(meta);
            routes.add(route);
        }

        List<Route> routeList = RouteTreeUtils.buildRouteTree(routes);

        return Result.success(routeList);
    }
    @Override
    public UserHolder getUserInfo2() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request;
        UserHolder userHolder = new UserHolder();
        if (Objects.nonNull(attributes)) {
            request = attributes.getRequest();
            // 从head中获取token
            String token = request.getHeader(UserConstant.ACCESS_TOKEN);
            // 从token中解析userName
            String account = JWTUtils.getTokenInfo(token, "account");
            log.info("登录的账号为为：【{}】", account);

            // 获取用户信息
            QueryWrapper<SysUser> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.eq("user_account", account);
            SysUser sysUser = userMapper.selectOne(userQueryWrapper);
            userHolder.setSysUser(sysUser);
        }
        return userHolder;
    }
    @Override
    public UserHolder getUserInfo() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request;

        UserHolder userHolder = new UserHolder();

        if (Objects.nonNull(attributes)) {
            request = attributes.getRequest();
            // 从head中获取token
            String token = request.getHeader(UserConstant.ACCESS_TOKEN);
            // 从token中解析userName
            String account = JWTUtils.getTokenInfo(token, "account");
            log.info("登录的账号为为：【{}】", account);

            // 获取用户信息
            QueryWrapper<SysUser> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.eq("user_account", account);
            SysUser sysUser = userMapper.selectOne(userQueryWrapper);

            // 获取用户与角色关联信息
            QueryWrapper<SysUserRole> userRoleQueryWrapper = new QueryWrapper<>();
            userRoleQueryWrapper.eq("user_id", sysUser.getUserId());
            List<SysUserRole> sysUserRoleList = userRoleMapper.selectList(userRoleQueryWrapper);

            // 获取角色信息
            List<SysRole> roleList = new ArrayList<>();
            for (SysUserRole sysUserRole : sysUserRoleList) {
                SysRole sysRole = roleMapper.selectById(sysUserRole.getRoleId());
                roleList.add(sysRole);
            }

            // 获取角色与菜单关联信息
            List<SysRoleMenu> roleMenuList = new ArrayList<>();
            for (SysRole sysRole : roleList) {
                QueryWrapper<SysRoleMenu> roleMenuQueryWrapper = new QueryWrapper<>();
                roleMenuQueryWrapper.eq("role_id", sysRole.getRoleId());
                List<SysRoleMenu> sysRoleMenuList = roleMenuMapper.selectList(roleMenuQueryWrapper);
                roleMenuList.addAll(sysRoleMenuList);
            }

            // 获取菜单信息
            List<SysMenu> menuList = new ArrayList<>();
            for (SysRoleMenu sysRoleMenu : roleMenuList) {
                SysMenu menu = menuMapper.selectById(sysRoleMenu.getMenuId());
                menuList.add(menu);
            }
            // 菜单按照order_num排序
            menuList.sort(new MenuComparator());

            userHolder.setSysUser(sysUser);
            userHolder.setRoleList(roleList);
            userHolder.setMenuList(menuList);

            return userHolder;
        }
        return userHolder;
    }

    @Override
    public Result<Object> changePassword(SysUserVo sysUserVo) {
        SysUser sysUser = getUserInfo().getSysUser();
        String oldUserPassword = sysUser.getUserPassword();
        String userPassword = sysUserVo.getUserPassword();
        String newUserPassword = sysUserVo.getNewUserPassword();

        if (userPassword.equals(oldUserPassword)) {
            sysUser.setUserPassword(newUserPassword);
            updateById(sysUser);
        }

        return Result.returnMsg("修改密码失败，输入的原始密码错误！", ResultCode.FAILED.getCode());
    }

    @Override
    public Result<Object> manageUser() {
        List<SysUser> adminUserList = getAdmin();

        List<String> ids = new ArrayList<>();
        adminUserList.forEach(sysUser -> ids.add(sysUser.getUserId()));
        userManageService.remove(new QueryWrapper<UserManage>().in("manage_id", ids));

        List<SysUser> sysUserList = list();
        for (String manageId : ids) {
            for (SysUser sysUser : sysUserList) {
                userManageService.save(new UserManage(manageId, sysUser.getUserId()));
            }
        }

        return Result.success();
    }

    @Override
    public Result<Object> manageProject() {
        List<SysUser> adminUserList = getAdmin();

        List<String> ids = new ArrayList<>();
        adminUserList.forEach(sysUser -> ids.add(sysUser.getUserId()));
        userProjectService.remove(new QueryWrapper<UserProject>().in("user_id", ids));

        List<Project> projectList = projectService.list();
        for (String userId : ids) {
            for (Project project : projectList) {
                userProjectService.save(new UserProject(userId, project.getId()));
            }
        }

        return Result.success();
    }

    /**
     * 获取所有管理员账号信息
     *
     * @return 所有管理员账号信息
     */
    private List<SysUser> getAdmin() {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_key", UserConstant.TOP_ROLE1).or().eq("role_key", UserConstant.TOP_AGENCIES);
        return getUsers(queryWrapper);
    }

    private List<SysUser> getUsers(QueryWrapper<SysRole> queryWrapper) {
        List<SysRole> sysRoleList = roleMapper.selectList(queryWrapper);
        List<SysUser> sysUserList = new ArrayList<>();
        for (SysRole sysRole : sysRoleList) {
            List<SysUserRole> sysUserRoleList = userRoleMapper.selectList(new QueryWrapper<SysUserRole>().eq("role_id", sysRole.getRoleId()));
            sysUserRoleList.forEach(sysUserRole -> sysUserList.add(userMapper.selectById(sysUserRole.getUserId())));
        }
        return sysUserList;
    }


}